/*
 * 
 *  This file is part of Sourceprojects.org Lycia Copyright 2010 noctarius
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 */
package org.sourceprojects.lycia;

import java.io.Serializable;

import javax.xml.XMLConstants;

/**
 * QualifiedName is a class similar to javax.xml.namespace.QName but since this
 * class isn't available on all platforms Lycia supports there is an alternative
 * to use.
 * 
 * @author noctarius
 * @since 1.9.9
 */
public class QualifiedName implements Serializable {
	private static final long serialVersionUID = -4777508166284919095L;

	private final String namespaceURI;
	private final String localPart;
	private final String prefix;

	/**
	 * Creates a new {@link QualifiedName} with given namespaceURI and local
	 * name of the element and a Null-Prefix (default namespace).
	 * 
	 * @param namespaceURI
	 *            The namespaceURI to use
	 * @param localPart
	 *            The local name to use
	 */
	public QualifiedName(final String namespaceURI, final String localPart) {
		this(namespaceURI, localPart, XMLConstants.DEFAULT_NS_PREFIX);
	}

	/**
	 * Creates a new {@link QualifiedName} with given namespaceURI, local name
	 * and prefix of the element .
	 * 
	 * @param namespaceURI
	 *            The namespaceURI to use
	 * @param localPart
	 *            The local name to use
	 * @param prefix
	 *            The prefix to be used for the namespaceURI
	 */
	public QualifiedName(final String namespaceURI, final String localPart,
			final String prefix) {
		if (namespaceURI == null) {
			this.namespaceURI = XMLConstants.NULL_NS_URI;
		} else {
			this.namespaceURI = namespaceURI;
		}

		if (localPart == null) {
			throw new IllegalArgumentException(
					"local part cannot be \"null\" when creating a QualifiedName");
		}

		this.localPart = localPart;

		if (prefix == null) {
			throw new IllegalArgumentException(
					"prefix cannot be \"null\" when creating a QualifiedName");
		}

		this.prefix = prefix;
	}

	/**
	 * Creates a new {@link QualifiedName} with local name of the element and a
	 * Null-Namespace / Null-Namespaceprefix.
	 * 
	 * @param localPart
	 *            The local name to use
	 */
	public QualifiedName(final String localPart) {
		this(XMLConstants.NULL_NS_URI, localPart,
				XMLConstants.DEFAULT_NS_PREFIX);
	}

	/**
	 * Returns the namespaceURI of the actual element.
	 * 
	 * @return The namespaceURI as a String
	 */
	public String getNamespaceURI() {
		return namespaceURI;
	}

	/**
	 * Returns the local name of the actual element.
	 * 
	 * @return The local name as a String
	 */
	public String getLocalPart() {
		return localPart;
	}

	/**
	 * Returns the namespace prefix of the actual element.
	 * 
	 * @return The namespace prefix as a String
	 */
	public String getPrefix() {
		return prefix;
	}

	@Override
	public String toString() {
		if (namespaceURI.equals(XMLConstants.NULL_NS_URI)) {
			return localPart;
		} else {
			return "{" + namespaceURI + "}" + localPart;
		}
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((localPart == null) ? 0 : localPart.hashCode());
		result = prime * result
				+ ((namespaceURI == null) ? 0 : namespaceURI.hashCode());
		result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		QualifiedName other = (QualifiedName) obj;
		if (localPart == null) {
			if (other.localPart != null)
				return false;
		} else if (!localPart.equals(other.localPart))
			return false;
		if (namespaceURI == null) {
			if (other.namespaceURI != null)
				return false;
		} else if (!namespaceURI.equals(other.namespaceURI))
			return false;
		if (prefix == null) {
			if (other.prefix != null)
				return false;
		} else if (!prefix.equals(other.prefix))
			return false;
		return true;
	}

}
